/**
 * 多端适配工具类
 * 处理不同平台（H5、小程序、APP）的差异化功能
 */

type Platform = 'h5' | 'mp-weixin' | 'mp-alipay' | 'mp-baidu' | 'mp-toutiao' | 'mp-qq' | 'app-plus' | 'app-nvue';

interface PlatformInfo {
  platform: Platform;
  isH5: boolean;
  isMiniProgram: boolean;
  isApp: boolean;
  isWeixin: boolean;
  isAlipay: boolean;
  isBaidu: boolean;
  isToutiao: boolean;
  isQQ: boolean;
  systemInfo: any;
}

interface ShareOptions {
  title: string;
  desc?: string;
  path?: string;
  imageUrl?: string;
  type?: 'text' | 'image' | 'music' | 'video' | 'webpage';
}

interface PaymentOptions {
  provider: 'wxpay' | 'alipay' | 'baidu' | 'appleiap';
  orderInfo: any;
  success?: (res: any) => void;
  fail?: (err: any) => void;
}

interface LocationOptions {
  type?: 'wgs84' | 'gcj02';
  success?: (res: any) => void;
  fail?: (err: any) => void;
}

class PlatformAdapter {
  private static instance: PlatformAdapter;
  private platformInfo: PlatformInfo;
  
  static getInstance(): PlatformAdapter {
    if (!PlatformAdapter.instance) {
      PlatformAdapter.instance = new PlatformAdapter();
    }
    return PlatformAdapter.instance;
  }
  
  constructor() {
    this.platformInfo = this.detectPlatform();
  }
  
  /**
   * 检测当前平台
   */
  private detectPlatform(): PlatformInfo {
    let platform: Platform = 'h5';
    let systemInfo: any = {};
    
    // uni-app环境
    if (typeof uni !== 'undefined') {
      try {
        systemInfo = uni.getSystemInfoSync();
        platform = systemInfo.uniPlatform || systemInfo.platform;
      } catch (e) {
        console.warn('Failed to get system info:', e);
      }
    }
    // Web环境
    else if (typeof window !== 'undefined') {
      platform = 'h5';
      systemInfo = {
        platform: 'web',
        system: navigator.userAgent,
        version: navigator.appVersion
      };
    }
    
    return {
      platform,
      isH5: platform === 'h5',
      isMiniProgram: platform.startsWith('mp-'),
      isApp: platform.startsWith('app-'),
      isWeixin: platform === 'mp-weixin',
      isAlipay: platform === 'mp-alipay',
      isBaidu: platform === 'mp-baidu',
      isToutiao: platform === 'mp-toutiao',
      isQQ: platform === 'mp-qq',
      systemInfo
    };
  }
  
  /**
   * 获取平台信息
   */
  getPlatformInfo(): PlatformInfo {
    return this.platformInfo;
  }
  
  /**
   * 是否支持某个功能
   */
  isFeatureSupported(feature: string): boolean {
    const featureMap: { [key: string]: Platform[] } = {
      'share': ['mp-weixin', 'mp-alipay', 'mp-baidu', 'mp-toutiao', 'mp-qq', 'app-plus'],
      'payment': ['mp-weixin', 'mp-alipay', 'app-plus', 'h5'],
      'location': ['mp-weixin', 'mp-alipay', 'mp-baidu', 'app-plus', 'h5'],
      'camera': ['mp-weixin', 'mp-alipay', 'mp-baidu', 'app-plus'],
      'bluetooth': ['mp-weixin', 'app-plus'],
      'nfc': ['app-plus'],
      'fingerprint': ['app-plus'],
      'faceId': ['app-plus'],
      'push': ['mp-weixin', 'app-plus'],
      'clipboard': ['mp-weixin', 'mp-alipay', 'app-plus', 'h5'],
      'vibrate': ['mp-weixin', 'mp-alipay', 'app-plus'],
      'brightness': ['app-plus'],
      'keepScreenOn': ['mp-weixin', 'app-plus']
    };
    
    const supportedPlatforms = featureMap[feature];
    return supportedPlatforms ? supportedPlatforms.includes(this.platformInfo.platform) : false;
  }
  
  /**
   * 统一的分享功能
   */
  async share(options: ShareOptions): Promise<void> {
    if (!this.isFeatureSupported('share')) {
      throw new Error('Share not supported on this platform');
    }
    
    return new Promise((resolve, reject) => {
      if (this.platformInfo.isWeixin) {
        // 微信小程序分享
        uni.showShareMenu({
          withShareTicket: true,
          success: () => resolve(),
          fail: reject
        });
      } else if (this.platformInfo.isAlipay) {
        // 支付宝小程序分享
        // @ts-ignore
        my.showSharePanel({
          title: options.title,
          desc: options.desc,
          path: options.path,
          success: () => resolve(),
          fail: reject
        });
      } else if (this.platformInfo.isApp) {
        // APP分享
        uni.share({
          provider: 'weixin',
          scene: 'WXSceneSession',
          type: 0,
          href: options.path,
          title: options.title,
          summary: options.desc,
          imageUrl: options.imageUrl,
          success: () => resolve(),
          fail: reject
        });
      } else {
        reject(new Error('Share not implemented for this platform'));
      }
    });
  }
  
  /**
   * 统一的支付功能
   */
  async payment(options: PaymentOptions): Promise<any> {
    if (!this.isFeatureSupported('payment')) {
      throw new Error('Payment not supported on this platform');
    }
    
    return new Promise((resolve, reject) => {
      if (this.platformInfo.isMiniProgram) {
        // 小程序支付
        uni.requestPayment({
          provider: options.provider,
          ...options.orderInfo,
          success: (res: any) => {
            options.success?.(res);
            resolve(res);
          },
          fail: (err: any) => {
            options.fail?.(err);
            reject(err);
          }
        });
      } else if (this.platformInfo.isApp) {
        // APP支付
        uni.requestPayment({
          provider: options.provider,
          orderInfo: options.orderInfo,
          success: (res) => {
            options.success?.(res);
            resolve(res);
          },
          fail: (err) => {
            options.fail?.(err);
            reject(err);
          }
        });
      } else if (this.platformInfo.isH5) {
        // H5支付（跳转到支付页面）
        if (options.provider === 'alipay') {
          window.location.href = options.orderInfo.payUrl;
        } else {
          // 微信H5支付等
          window.location.href = options.orderInfo.mwebUrl;
        }
        resolve({ success: true });
      } else {
        reject(new Error('Payment not implemented for this platform'));
      }
    });
  }
  
  /**
   * 统一的定位功能
   */
  async getLocation(options: LocationOptions = {}): Promise<any> {
    if (!this.isFeatureSupported('location')) {
      throw new Error('Location not supported on this platform');
    }
    
    return new Promise((resolve, reject) => {
      if (this.platformInfo.isMiniProgram || this.platformInfo.isApp) {
        uni.getLocation({
          type: options.type || 'wgs84',
          success: (res) => {
            options.success?.(res);
            resolve(res);
          },
          fail: (err) => {
            options.fail?.(err);
            reject(err);
          }
        });
      } else if (this.platformInfo.isH5) {
        // H5定位
        if (navigator.geolocation) {
          navigator.geolocation.getCurrentPosition(
            (position) => {
              const res = {
                latitude: position.coords.latitude,
                longitude: position.coords.longitude,
                accuracy: position.coords.accuracy
              };
              options.success?.(res);
              resolve(res);
            },
            (error) => {
              options.fail?.(error);
              reject(error);
            }
          );
        } else {
          reject(new Error('Geolocation not supported'));
        }
      } else {
        reject(new Error('Location not implemented for this platform'));
      }
    });
  }
  
  /**
   * 统一的剪贴板功能
   */
  async setClipboardData(data: string): Promise<void> {
    if (!this.isFeatureSupported('clipboard')) {
      throw new Error('Clipboard not supported on this platform');
    }
    
    return new Promise((resolve, reject) => {
      if (this.platformInfo.isMiniProgram || this.platformInfo.isApp) {
        uni.setClipboardData({
          data,
          success: () => resolve(),
          fail: reject
        });
      } else if (this.platformInfo.isH5) {
        if (navigator.clipboard) {
          navigator.clipboard.writeText(data)
            .then(() => resolve())
            .catch(reject);
        } else {
          // 降级方案
          const textArea = document.createElement('textarea');
          textArea.value = data;
          document.body.appendChild(textArea);
          textArea.select();
          try {
            document.execCommand('copy');
            resolve();
          } catch (err) {
            reject(err);
          } finally {
            document.body.removeChild(textArea);
          }
        }
      } else {
        reject(new Error('Clipboard not implemented for this platform'));
      }
    });
  }
  
  /**
   * 统一的震动功能
   */
  async vibrate(type: 'short' | 'long' = 'short'): Promise<void> {
    if (!this.isFeatureSupported('vibrate')) {
      return; // 不支持震动的平台静默忽略
    }
    
    return new Promise((resolve) => {
      if (this.platformInfo.isMiniProgram || this.platformInfo.isApp) {
        if (type === 'short') {
          uni.vibrateShort({
            success: () => resolve(),
            fail: () => resolve() // 失败也继续
          });
        } else {
          uni.vibrateLong({
            success: () => resolve(),
            fail: () => resolve()
          });
        }
      } else {
        resolve();
      }
    });
  }
  
  /**
   * 统一的导航栏设置
   */
  setNavigationBar(options: {
    title?: string;
    backgroundColor?: string;
    frontColor?: '#ffffff' | '#000000';
  }): void {
    if (this.platformInfo.isMiniProgram || this.platformInfo.isApp) {
      if (options.title) {
        uni.setNavigationBarTitle({
          title: options.title
        });
      }
      
      if (options.backgroundColor || options.frontColor) {
        uni.setNavigationBarColor({
          backgroundColor: options.backgroundColor || '#ffffff',
          frontColor: options.frontColor || '#000000'
        });
      }
    } else if (this.platformInfo.isH5) {
      // H5设置页面标题
      if (options.title) {
        document.title = options.title;
      }
    }
  }
  
  /**
   * 统一的状态栏设置
   */
  setStatusBar(style: 'light' | 'dark'): void {
    if (this.platformInfo.isApp) {
      // APP状态栏设置
      // @ts-ignore
      if (plus && plus.navigator) {
        const statusBarStyle = style === 'light' ? 'UIStatusBarStyleLightContent' : 'UIStatusBarStyleDefault';
        // @ts-ignore
        plus.navigator.setStatusBarStyle(statusBarStyle);
      }
    }
  }
  
  /**
   * 统一的存储功能
   */
  storage = {
    set: (key: string, value: any): void => {
      try {
        if (typeof uni !== 'undefined') {
          uni.setStorageSync(key, value);
        } else if (typeof localStorage !== 'undefined') {
          localStorage.setItem(key, JSON.stringify(value));
        }
      } catch (e) {
        console.warn('Storage set failed:', e);
      }
    },
    
    get: (key: string): any => {
      try {
        if (typeof uni !== 'undefined') {
          return uni.getStorageSync(key);
        } else if (typeof localStorage !== 'undefined') {
          const value = localStorage.getItem(key);
          return value ? JSON.parse(value) : null;
        }
      } catch (e) {
        console.warn('Storage get failed:', e);
        return null;
      }
    },
    
    remove: (key: string): void => {
      try {
        if (typeof uni !== 'undefined') {
          uni.removeStorageSync(key);
        } else if (typeof localStorage !== 'undefined') {
          localStorage.removeItem(key);
        }
      } catch (e) {
        console.warn('Storage remove failed:', e);
      }
    },
    
    clear: (): void => {
      try {
        if (typeof uni !== 'undefined') {
          uni.clearStorageSync();
        } else if (typeof localStorage !== 'undefined') {
          localStorage.clear();
        }
      } catch (e) {
        console.warn('Storage clear failed:', e);
      }
    }
  };
  
  /**
   * 统一的网络请求
   */
  request = {
    upload: (options: {
      url: string;
      filePath: string;
      name: string;
      formData?: any;
      success?: (res: any) => void;
      fail?: (err: any) => void;
    }): Promise<any> => {
      return new Promise((resolve, reject) => {
        if (typeof uni !== 'undefined') {
          uni.uploadFile({
            ...options,
            success: (res) => {
              options.success?.(res);
              resolve(res);
            },
            fail: (err) => {
              options.fail?.(err);
              reject(err);
            }
          });
        } else {
          // H5文件上传
          const formData = new FormData();
          
          // 这里需要根据实际情况处理文件
          if (options.formData) {
            Object.keys(options.formData).forEach(key => {
              formData.append(key, options.formData[key]);
            });
          }
          
          fetch(options.url, {
            method: 'POST',
            body: formData
          })
          .then(response => response.json())
          .then(data => {
            options.success?.(data);
            resolve(data);
          })
          .catch(error => {
            options.fail?.(error);
            reject(error);
          });
        }
      });
    }
  };
  
  /**
   * 获取设备信息
   */
  getDeviceInfo(): any {
    return this.platformInfo.systemInfo;
  }
  
  /**
   * 获取安全区域信息
   */
  getSafeAreaInsets(): {
    top: number;
    bottom: number;
    left: number;
    right: number;
  } {
    const systemInfo = this.platformInfo.systemInfo;
    
    if (systemInfo.safeAreaInsets) {
      return systemInfo.safeAreaInsets;
    }
    
    // 默认值
    return {
      top: systemInfo.statusBarHeight || 0,
      bottom: 0,
      left: 0,
      right: 0
    };
  }
  
  /**
   * 检查更新（仅小程序）
   */
  checkUpdate(): void {
    if (this.platformInfo.isMiniProgram && typeof uni !== 'undefined') {
      const updateManager = uni.getUpdateManager();
      
      updateManager.onCheckForUpdate((res) => {
        console.log('检查更新结果:', res.hasUpdate);
      });
      
      updateManager.onUpdateReady(() => {
        uni.showModal({
          title: '更新提示',
          content: '新版本已经准备好，是否重启应用？',
          success: (res) => {
            if (res.confirm) {
              updateManager.applyUpdate();
            }
          }
        });
      });
      
      updateManager.onUpdateFailed(() => {
        console.warn('新版本下载失败');
      });
    }
  }
}

// 导出单例实例
export const platformAdapter = PlatformAdapter.getInstance();

// 导出便捷方法
export const platform = {
  info: () => platformAdapter.getPlatformInfo(),
  isSupported: (feature: string) => platformAdapter.isFeatureSupported(feature),
  share: (options: ShareOptions) => platformAdapter.share(options),
  payment: (options: PaymentOptions) => platformAdapter.payment(options),
  getLocation: (options?: LocationOptions) => platformAdapter.getLocation(options),
  setClipboard: (data: string) => platformAdapter.setClipboardData(data),
  vibrate: (type?: 'short' | 'long') => platformAdapter.vibrate(type),
  setNavigationBar: (options: any) => platformAdapter.setNavigationBar(options),
  setStatusBar: (style: 'light' | 'dark') => platformAdapter.setStatusBar(style),
  storage: platformAdapter.storage,
  request: platformAdapter.request,
  getDeviceInfo: () => platformAdapter.getDeviceInfo(),
  getSafeAreaInsets: () => platformAdapter.getSafeAreaInsets(),
  checkUpdate: () => platformAdapter.checkUpdate()
};

// 导出类型
export type { Platform, PlatformInfo, ShareOptions, PaymentOptions, LocationOptions };